package handlers

import (
	"math"
	"restaurant-system/config"
	"restaurant-system/internal/models"
	"restaurant-system/pkg/maps"
	"sort"

	"github.com/gin-gonic/gin"
)

// 创建门店请求
type CreateStoreRequest struct {
	Name        string  `json:"name" binding:"required"`
	Address     string  `json:"address" binding:"required"`
	Latitude    float64 `json:"latitude" binding:"required"`
	Longitude   float64 `json:"longitude" binding:"required"`
	Phone       string  `json:"phone" binding:"required"`
	OpenTime    string  `json:"open_time" binding:"required"`
	Description string  `json:"description"`
	ImageURL    string  `json:"image_url"`
	MinAmount   float64 `json:"min_amount" binding:"required,gte=0"`
	DeliveryFee float64 `json:"delivery_fee" binding:"required,gte=0"`
	Area        string  `json:"area" binding:"required"`
}

// 创建门店
func CreateStore(c *gin.Context) {
	var req CreateStoreRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	store := models.Store{
		Name:        req.Name,
		Address:     req.Address,
		Latitude:    req.Latitude,
		Longitude:   req.Longitude,
		Phone:       req.Phone,
		OpenTime:    req.OpenTime,
		Status:      "open",
		Description: req.Description,
		ImageURL:    req.ImageURL,
		MinAmount:   req.MinAmount,
		DeliveryFee: req.DeliveryFee,
		Area:        req.Area,
	}

	if err := config.DB.Create(&store).Error; err != nil {
		c.JSON(500, gin.H{"error": "创建门店失败"})
		return
	}

	c.JSON(200, gin.H{"message": "创建门店成功", "store": store})
}

// 获取附近门店
func GetNearbyStores(c *gin.Context) {
	var req struct {
		Latitude  float64 `form:"latitude" binding:"required"`
		Longitude float64 `form:"longitude" binding:"required"`
		Distance  float64 `form:"distance,default=5"` // 默认5公里范围内
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	var stores []models.Store
	// 使用 MySQL 空间索引查询附近门店
	latRange := req.Distance / 111.0 // 粗略计算：1度纬度约111公里
	lonRange := req.Distance / (111.0 * math.Cos(req.Latitude*math.Pi/180.0))

	if err := config.DB.Where("latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ?",
		req.Latitude-latRange, req.Latitude+latRange,
		req.Longitude-lonRange, req.Longitude+lonRange).
		Find(&stores).Error; err != nil {
		c.JSON(500, gin.H{"error": "获取门店列表失败"})
		return
	}

	// 计算实际距离并排序
	type StoreWithDistance struct {
		models.Store
		Distance float64 `json:"distance"`
	}

	var result []StoreWithDistance
	for _, store := range stores {
		distance := maps.CalculateDistance(req.Latitude, req.Longitude, store.Latitude, store.Longitude)
		if distance <= req.Distance {
			result = append(result, StoreWithDistance{
				Store:    store,
				Distance: distance,
			})
		}
	}

	// 按距离排序
	sort.Slice(result, func(i, j int) bool {
		return result[i].Distance < result[j].Distance
	})

	// 确保返回空数组而不是 null
	if result == nil {
		result = []StoreWithDistance{}
	}

	c.JSON(200, gin.H{"stores": result})
}

// 获取门店详情
func GetStore(c *gin.Context) {
	storeID := c.Param("id")

	var store models.Store
	if err := config.DB.First(&store, storeID).Error; err != nil {
		c.JSON(404, gin.H{"error": "门店不存在"})
		return
	}

	c.JSON(200, gin.H{"store": store})
}
